
/*
 * INIT             : Initial state. Point start. the appropriate serve/receive area 
 *                    is highlighted based on which button is clicked.
 * SERV_READY       : Serv position ready. Transitions is based on what is tapped
 *                    for a serve. If its a fault, the app stays in this state.
 * INPLAY           : Ball is inplay. Serv is successful and ball is returned.
 *                    Error and winning areas are enabled.
 * RECV_READY       : 
 * RECV_READY       : Recv position ready. Transitions is based on what is tapped
 *                    for a opponent serve. If its a fault, the app stays in this state.
 * END              : Point is over. Score it and go back to INIT.
 *
 *
 * All the #<name> elements are basically the div ids which represent a clickable area.
 * The # is a jquery style.
 * 
 * Here are the details of the location.
 * #rse = right serving error. (When serving from right side, the error aisle on the top left side)
 * #cm = center mark. (big area on the top half of the court).
 * #lse = left serving error. (When serving from left side, the error aisle on the top right side)
 * #rsc = right serving court. (When serving from right side, the service court on the top right side)
 * #lsc = left serving court. (When serving from left side, the service court on the top left side)

 * #net_r = net error area for right side serve.
 * #rsc_ace = ace box on #rsc
 * #rsc_winner = winner box on #rsc
 * #rsc_return = return box on #rsc
 * same for lsc_* but on #lsc
 
 * All ids starting with b_* are for the bottom half of the court, when opponent is serving.

 */

var STATES = {INIT:0, SERV_READY:1, RECV_READY:2, FIRST_SERV:3, INPLAY:4, END:5};
var curState = STATES.INIT;
var toggleServ=0;
var toggleServPos=0;
var toggleRecv=0;
var toggleRecvPos=0;
var first_serv=0;
var email="";
var desc="";
var winner="";
var debug=0;
var max_id = 0;


var db;
try {
    if (window.openDatabase) {
        db = openDatabase("DoubleFault", "1.0", "Double Fault Stats", 200000);
        if (!db)
            showAlert("Failed to open the database on disk.  This is probably because the version was bad or there is not enough space left in this domain's quota");
    } 
    else
        showAlert("Couldn't open the database.  Please try with a WebKit nightly with this feature enabled");
} 
catch(err) { }


//Create the DB
function create_db() {
  db.transaction(function(tx) {
    tx.executeSql('CREATE TABLE IF NOT EXISTS DoubleFault(id REAL UNIQUE, timestamp REAL, email TEXT, player TEXT, opponent TEXT, p1_df INTEGER, p2_df INTEGER, p1_neterrs INTEGER, p2_neterrs INTEGER, p1_aces INTEGER, p2_aces INTEGER, p1_aces2 INTEGER, p2_aces2 INTEGER, p1_wins INTEGER, p2_wins INTEGER, p1_wins2 INTEGER, p2_wins2 INTEGER, matchover INTEGER)', []);
    tx.executeSql('CREATE TABLE IF NOT EXISTS Scoreboard(id REAL UNIQUE, player TEXT, opponent TEXT, p1_score INTEGER, p2_score INTEGER, p1_set1 INTEGER, p2_set1 INTEGER, p1_set2 INTEGER, p2_set2 INTEGER, p1_set3 INTEGER, p2_set3 INTEGER, curset INTEGER, matchover INTEGER)', []);
  });
}


/*************** Objects ****************/
//Match object
function Match() {
    this.id = 0;
    this.timestamp = 0;
    this.email = "";
    this.player = "";
    this.opponent = "";
    this.matchover = 2;

}

var match = new Match();


//Player objects
function Player(name, id) {
    this.id = id;
    this.name = name;
    this.score = 0;
//    this.sets = new Array(0, 0, 0);
    this.sets = [0, 0, 0];
    this.games = 0;
    this.tb = 0;
    this.points = 0;

    this.dbl_flts=0;
    this.net_errs=0;
    this.serv_try=0;
    this.serves=0;
    this.aces=0;
    this.sec_aces=0;
    this.serv_winners=0;
    this.sec_serv_winners=0;
    this.unf_errs=0;

    this.reset = function() {
        this.score = 0;
        this.sets[0] = 0;
        this.sets[1] = 0;
        this.sets[2] = 0;
        this.games = 0;
        this.tb = 0;
        this.points = 0;

        this.dbl_flts=0;
        this.net_errs=0;
        this.serv_try=0;
        this.serves=0;
        this.aces=0;
        this.sec_aces=0;
        this.serv_winners=0;
        this.sec_serv_winners=0;
        this.unf_errs=0;
    };
}
var p1=new Player("P1", 1);
var p2=new Player("P2", 2);

function Scoreboard() {
    this.curset = 0;
    this.matchover = 0;
    this.tiebreak = 0;

    this.reset = function() {
        this.curset = 0;
        this.matchover = 0;
        this.tiebreak = 0;
    };

    this.incScore = function(player) {

        player.points++;

        if(this.tiebreak == 1) {
            player.tb++;
            $("#debug").html("Tiebreak " + p1.tb + " " + p2.tb);
            if((p1.tb > 6) && (p2.tb <= (p1.tb-2))) {
                p1.games++;
            }
            else if ((p2.tb > 6) && (p1.tb <= (p2.tb-2))) {
                p2.games++;
            }
            this.updateSet();
        }
        else {
            switch (player.score) {
            case 0:
                player.score=15;
                break;
            case 15:
                player.score=30;
                break;
            case 30:
                player.score=40;
                break;
            case 40:
                if(player.id == 1) {
                    p = p2;
                }
                else if(player.id == 2) {
                    p = p1;
                }

                if(p.score == 40) {
                    player.score = 'A';
                }
                else if(p.score == 'A') {
                    player.score = 40;
                    p.score = 40;
                }
                else {
                    player.games++;
                    this.updateSet();
                    p1.score=0;
                    p2.score=0;
                }
                break;
            case 'A':
                player.games++;
                this.updateSet();
                p1.score=0;
                p2.score=0;
                break;
            }
        }
        this.updateScore();
    };

    this.updateSet = function() {
        p1.sets[this.curset] = p1.games;
        p2.sets[this.curset] = p2.games;
        //set over
        if ((p1.games == 6 && p2.games < 5) || 
            (p1.games == 7 && p2.games <= 5) || 
            (p2.games == 6 && p1.games < 5) || 
            (p2.games == 7 && p1.games <= 5) ||
            (p1.games == 7 && p2.games == 6) ||
            (p2.games == 7 && p1.games == 6)) {

            if(p1.games > p2.games) {
                showAlert("Set Over. Winner " + p1.name);
            }
            else {
                showAlert("Set Over. Winner " + p2.name);
            }
            p1.games = 0;
            p2.games = 0;
            p1.tb = 0;
            p2.tb = 0;
            this.tiebreak = 0;
            this.curset++;
            if(this.curset >= 2) {
                this.isMatchOver();
            }
        }
        //tie break
        else if (p2.games == 6 && p1.games == 6) {
            this.tiebreak = 1;
            $('#comment').html('Tie Break');
            showAlert('Tie Break');
        }
    };

    this.isMatchOver = function() {
        var p1sets = 0;
        var p2sets = 0;

        for(i=0; i<3; i++) {
            if(p1.sets[i] > p2.sets[i]) {
                p1sets++;
            }
            else {
                p2sets++;
            }
        }
        if(p1sets > p2sets) {
            winner = p1.name;
        }
        else if(p2sets > p1sets) {
            winner = p2.name;
        }
        if(winner) {
            this.matchover = 1;
            matchOver();
        }
    };

    this.updateScore = function() {
        $('#debug').html("updateScore " + p1.score + " p2 " + p2.score);
        $('#p1_score').html(p1.score);
        $('#p1_name').html(p1.name);
        $('#p1_set1').html(p1.sets[0]);
        $('#p1_set2').html(p1.sets[1]);
        $('#p1_set3').html(p1.sets[2]);
        $('#p1_tb').html(p1.tb);
        $('#p2_score').html(p2.score);
        $('#p2_name').html(p2.name);
        $('#p2_set1').html(p2.sets[0]);
        $('#p2_set2').html(p2.sets[1]);
        $('#p2_set3').html(p2.sets[2]);
        $('#p2_tb').html(p2.tb);
    };


    this.update_score = function() {
        db.transaction(function (tx) {
            tx.executeSql("UPDATE Scoreboard SET player = ?, opponent = ?, p1_score = ?, p2_score = ?, p1_set1 = ?, p2_set1 = ?, p1_set2 = ?, p2_set2 = ?, p1_set3 = ?, p2_set3 = ?, curset = ?, matchover = ? WHERE id = ?", [p1.name, p2.name, p1.score, p2.score, p1.sets[0], p2.sets[0], p1.sets[1], p2.sets[1], p1.sets[2], p2.sets[2], sb.curset, sb.matchover, match.id],
            function(tx, rs) {
                showAlert("update_score success");
            },
            function(tx, err) {
                showAlert("update_score failed");
            });
        }); 
    };
}

var sb=new Scoreboard();


/**************** FUNCTIONS ***************/

//load archive from DB
function load_db() {
  //create the archive page from the db
  db.transaction(
  function(tx) {
    tx.executeSql('SELECT * FROM DoubleFault', [], 
    function(tx, rs) {

        //showAlert("load_db rows=" + rs.rows.length);
        for(var i = 0; i < rs.rows.length; i++) {
            var row = rs.rows.item(i);

            if (row['id'] > max_id) {
                max_id = row['id'];
            }

            //for complete matches populate the archive section
            if (row['matchover'] == 1) {
                showAlert("load_db: Saved match id=" + row['id']);
                var dt = new Date(row['timestamp']);
                var dtstr = dt.toUTCString();

                //populate the tables with archive data
                var htmlstr = 
                "<div id='archive_" + row['id'] + "'>" + 
                "<div class='toolbar'> <h1>" + dtstr + "</h1> <a href='#archive' class='button back'>Archive</a></div>" +
                "<table width='100%' border='1' cellspacing='0' cellpadding='3'>" +
                "<tr><td width=50%>Name</td><td>" + row['player'] + "</td><td>" + row['opponent'] + "</td></tr>" +
                "<tr><td>Double Faults</td><td>" + row['p1_df'] + "</td><td>" + row['p2_df'] + "</td></tr>" +
                "<tr><td>Net Errors</td><td>" + row['p1_neterrs'] + "</td><td>" + row['p2_neterrs'] + "</td></tr>" +
                "<tr><td>Aces 1st Serve</td><td>" + row['p1_aces'] + "</td><td>" + row['p2_aces'] + "</td></tr>" +
                "<tr><td>Aces 2nd Serve</td><td>" + row['p1_aces2'] + "</td><td>" + row['p2_aces2'] + "</td></tr>" +
                "<tr><td>1st Serve Winners</td><td>" + row['p1_wins'] + "</td><td>" + row['p2_wins'] + "</td></tr>" +
                "<tr><td>2nd Serve Winners</td><td>" + row['p1_wins2'] + "</td><td>" + row['p2_wins2'] + "</td></tr>" +
                "</table>" + 
                "</div>";
                $("body").append(htmlstr);
                
                var htmlstr = "<li class='arrow'><a href='#archive_" + row['id'] + "'>" + dtstr + "</a></li>";
                $("#archive > ul").append(htmlstr);
            }

            //for incomplete match, load the data for current match
            else if (row['matchover'] === 0) {
                showAlert("load_db: Incomplete match id=" + row['id']);
                match.id = row['id'];
                match.matchover = row['matchover'];
                email = row['email'];
                p1.name = row['player'];
                p2.name = row['opponent'];
                p1.dbl_flts = row['p1_df'];
                p2.dbl_flts = row['p2_df'];
                p1.net_errs = row['p1_neterrs'];
                p2.net_errs = row['p2_neterrs'];
                p1.aces = row['p1_aces'];
                p2.aces = row['p2_aces'];
                p1.sec_aces = row['p1_aces2'];
                p2.sec_aces = row['p2_aces2'];
                p1.serv_winners = row['p1_wins'];
                p2.serv_winners = row['p2_wins'];
                p1.sec_serv_winners = row['p1_wins2'];
                p2.sec_serv_winners = row['p2_wins2'];
            }
        }
    });
  });
}


//get any incomplete match entry
function load_match() {
  db.transaction(
  function(tx) {
    tx.executeSql('SELECT * FROM DoubleFault WHERE matchover = ?', [0], 
    function(tx, rs) {
        //there should only be one incomplete match in the db at any time
        if (rs.rows.length == 1) {
            var row = rs.rows.item(0);
        }
    });
  });
}


function load_score() {
  db.transaction(
  function(tx) {
    tx.executeSql('SELECT * FROM Scoreboard WHERE id = ?', [match.id], 
    function(tx, rs) {
        if (rs.rows.length == 1) {
            var row = rs.rows.item(0);
            p1.score = row['p1_score'];
            p2.score = row['p2_score'];
            p1.sets[0] = row['p1_set1'];
            p2.sets[0] = row['p2_set1'];
            p1.sets[1] = row['p1_set2'];
            p2.sets[1] = row['p2_set2'];
            p1.sets[2] = row['p1_set3'];
            p2.sets[2] = row['p2_set3'];
            sb.curset = row['curset'];
            sb.matchover = row['matchover'];
            p1.games = p1.sets[sb.curset];
            p2.games = p2.sets[sb.curset];
        }
    });
  });
}


function archive_clk() {
    sb.updateScore();
    if(match.id === 0) {
        match.matchover = 0;
        create_match();
        sb.update_score();
    }
    else {
        sb.update_score();
        update_match();
    }
}


function reset() {
    sb.reset();
    p1.reset();
    p2.reset();
    unbindAll();
}


function showAlert(msg) {
    if(debug == 1) {
        alert(msg);
        /*
        $('#alert').html(msg);
        $('#alert').fadeIn(400, function(){
            setTimeout("$('#alert').fadeOut(800)", 1000);
        });
        */
    }
}


function matchOver() {
    match.matchover = 1;
    update_match();
    alert("Winner is " + winner);
}


function init() {

    $('#lsc_ace, #lsc_winner, #lsc_return').hide();
    $('#rsc_ace, #rsc_winner, #rsc_return').hide();
    $('#b_lsc_ace, #b_lsc_winner, #b_lsc_return').hide();
    $('#b_rsc_ace, #b_rsc_winner, #b_rsc_return').hide();
    $('#net_r, #b_net_r, #net_l, #b_net_l').hide();

    $('.floaty').hideFloaty();

    /*
    delete_match(1);
    delete_match(2);
    delete_match(3);
    delete_match(4);
    */
    load_db();
    //load_match();
    load_score();
    sb.updateScore();

    if(debug === 0) {
        $("#debug").hide();
    }
    showAlert("Init done");

    $("#comment").html("Tap the S or R button to start a point");
}
    

//sm
function execute(id) {
    $('#debug').html('Old State = ' + curState + '->');
    switch (curState) {
    case STATES.INIT:

        unbindAll();

        if(id != "") {
            this.id = id;
        }

        //bind for SERV_READY
        if(this.id == "servposr") {
            $('#rse, #cm, #lse, #lsc').addClass('highlightr');
            $('#rse, #cm, #lse, #lsc').bind('click', execute);

            $('#rsc_ace, #rsc_winner, #rsc_return, #net_r').show();
            $('#rsc_ace, #rsc_winner, #rsc_return, #net_r').bind('click', execute);

            curState = STATES.SERV_READY;
        }
        else if(this.id == "servposl") {
            $('#rse, #cm, #lse, #rsc').addClass('highlightr');
            $('#lsc_ace, #lsc_winner, #lsc_return').show();
            $('#lsc_ace, #lsc_winner, #lsc_return').bind('click', execute);
            $('#rse, #cm, #lse, #rsc').bind('click', execute);
            $('#net_l').bind('click', execute);
            $('#net_l').show();
            $('#debug').html('State = ' + curState + '->SERV_READY');
            curState = STATES.SERV_READY;
        }

        //bind for RECV_READY
        else if(this.id == "recvposr") {
            $('#b_rse, #b_cm, #b_lse, #b_lsc').addClass('highlightr');
            $('#b_rse, #b_cm, #b_lse, #b_lsc').bind('click', execute);
            $('#b_rsc_ace, #b_rsc_winner, #b_rsc_return').show();
            $('#b_rsc_ace, #b_rsc_winner, #b_rsc_return').bind('click', execute);
            $('#b_net_l').bind('click', execute);
            $('#b_net_l').show();
            $('#debug').html('State = ' + curState + '->RECV_READY');
            curState = STATES.RECV_READY;
        }
        else if(this.id == "recvposl") {
            $('#b_rse, #b_cm, #b_lse, #b_rsc').addClass('highlightr');
            $('#b_rse, #b_cm, #b_lse, #b_rsc').bind('click', execute);
            $('#b_lsc_ace, #b_lsc_winner, #b_lsc_return').show();
            $('#b_lsc_ace, #b_lsc_winner, #b_lsc_return').bind('click', execute);
            $('#b_net_r').bind('click', execute);
            $('#b_net_r').show();
            $('#debug').html('State = ' + curState + '->RECV_READY');
            curState = STATES.RECV_READY;
        }
        else {
            $('#debug').html('Invalid event = ' + curState + '->INIT');
            curState = STATES.INIT;
        }
        $('#comment').html("Tap the highlighted area as per the play");
        break;
    case STATES.SERV_READY:
        p1.serves++;
        //use a variable for the id, to reduce multiple checks and code
        if(toggleServ === 0) {
            id_ace="rsc_ace";
            id_winner="rsc_winner";
            id_return="rsc_return";
            id_net="net_r";
        }
        else if(toggleServ == 1) {
            id_ace="lsc_ace";
            id_winner="lsc_winner";
            id_return="lsc_return";
            id_net="net_l";
        }

        //check the area clicked and take action
        if(this.id == id_winner) {
            //increment winner count for p1 and move to END
            sb.incScore(p1);
            
            if(first_serv == 1) {
                p1.sec_serv_winners++;
            }
            else {
                p1.serv_winners++;
            }
            $('#comment').html(p1.name + " Hit a winner");
            curState = STATES.END;
            execute();
        }
        else if(this.id == id_ace) {
            //increment ace count for p1 and move to END
            sb.incScore(p1);
            if(first_serv == 1) {
                p1.sec_aces++;
            }
            else {
                p1.aces++;
            }
            $('#comment').html(p1.name + " Hit an Ace");
            curState = STATES.END;
            execute();
        }
        else if(this.id == id_return) {
            moveToINPLAY();
        }
        else {
            if(first_serv == 1) {
                $('#debug').html('State = ' + curState + '->END');
                first_serv = 0;
                p1.dbl_flts++;
                sb.incScore(p2);
                curState = STATES.END;
                execute();
                break;
            }

            first_serv = 1;

            if(toggleServ === 0) {
                $('#rse, #cm, #lse, #lsc').removeClass('highlightr');
                $('#net_r').removeClass('highlight');
                $('#rse, #cm, #lse, #lsc, #net_r').addClass('highlight2');
            }
            else if(toggleServ == 1) {
                $('#rse, #cm, #lse, #rsc').removeClass('highlightr');
                $('#net_l').removeClass('highlight');
                $('#rse, #cm, #lse, #rsc, #net_l').addClass('highlight2');
            }

            if(this.id == id_net) {
                $('#debug').html('State = ' + curState + '->Net');
                p1.net_errs++;
            }
            
            //since its a first serve, keep all highlightling.
            $('#debug').html('State = ' + curState + '->SERV_READY');
            $('#comment').html('First Serve');
            curState = STATES.SERV_READY;
        }
        break;

    //RECEIVING
    case STATES.RECV_READY:
        p2.serves++;
        //use a variable for the id, to reduce multiple checks
        if(toggleRecv === 0) {
            id_ace="b_rsc_ace";
            id_winner="b_rsc_winner";
            id_return="b_rsc_return";
            id_net="b_net_l";
        }
        else if(toggleRecv == 1) {
            id_ace="b_lsc_ace";
            id_winner="b_lsc_winner";
            id_return="b_lsc_return";
            id_net="b_net_r";
        }

        if(this.id == id_winner) {
            //increment winner count for p2 and move to END
            sb.incScore(p2);
            
            if(first_serv == 1) {
                p2.sec_serv_winners++;
            }
            else {
                p2.serv_winners++;
            }
            $('#comment').html(p1.name + " Hit a winner");
            curState = STATES.END;
            execute();
        }
        else if(this.id == id_ace) {
            //increment ace count for p2 and move to END
            sb.incScore(p2);
            if(first_serv == 1) {
                p2.sec_aces++;
            }
            else {
                p2.aces++;
            }
            $('#comment').html(p1.name + " Hit an Ace");
            curState = STATES.END;
            execute();
        }
        else if(this.id == id_return) {
            moveToINPLAY();
        }
        else {
            if(first_serv == 1) {
                $('#debug').html('State = ' + curState + '->END');
                first_serv = 0;
                p2.dbl_flts++;
                sb.incScore(p1);
                curState = STATES.END;
                execute();
                break;
            }

            first_serv = 1;

            if(toggleRecv === 0) {
                $('#b_rse, #b_cm, #b_lse, #b_lsc').removeClass('highlightr');
                $('#b_net_l').removeClass('highlight');
                $('#b_rse, #b_cm, #b_lse, #b_lsc, #b_net_l').addClass('highlight2');
            }
            else if(toggleRecv == 1) {
                $('#b_rse, #b_cm, #b_lse, #b_rsc').removeClass('highlightr');
                $('#b_net_r').removeClass('highlight');
                $('#b_rse, #b_cm, #b_lse, #b_rsc, #b_net_r').addClass('highlight2');
            }

            if(this.id == id_net) {
                $('#debug').html('State = ' + curState + '->Net');
                p1.net_errs++;
            }

            //since its a first serve, keep all highlightling and maintain the state.
            $('#debug').html('State = ' + curState + '->RECV_READY');
            $('#comment').html('First Serve');
            curState = STATES.RECV_READY;
        }
        break;
    case STATES.INPLAY:
        //score
        if( (this.id == "rse") || (this.id == "lse") || (this.id == "b_cm") ||
            (this.id == "b_net_l") || (this.id == "b_net_r") || (this.id == "out_err") ) {

            if ( (this.id == "b_net_l") || (this.id == "b_net_r") ) {
                p1.net_errs++;
            }
            p1.unf_errs++;
            sb.incScore(p2);
            $('#debug').html('INPLAY -> P2_WIN');
        }
        else {
            if ( (this.id == "net_l") || (this.id == "net_r") ) {
                p2.net_errs++;
            }
            p2.unf_errs++;
            sb.incScore(p1);
            $('#debug').html('INPLAY -> P1_WIN');
        }
        curState = STATES.END;
        execute();
        break;
    case STATES.END:
        //unbind
        unbindAll();
        showScore();
        $("#comment").html("Tap the S or R button to start a point");
        curState = STATES.INIT;
        break;
    default:
        break;
    }
    $('#debug').append('New State = ' + curState);
}


//Stats objects
function Stats() {
}

function startReceive()
{
    var id = "";
    if(first_serv == 1) {
        return;
    }

    if(toggleRecvPos === 0) {
        toggleRecv = 0;
        id = "recvposr";
        toggleRecvPos = 1;
    }
    else {
        toggleRecv = 1;
        id = "recvposl";
        toggleRecvPos = 0;
    }

    curState = STATES.INIT;

    execute(id);
}



function startServe()
{
    var id = "";
    if(first_serv == 1) {
        return;
    }

    if(toggleServPos === 0) {
        toggleServ = 0;
        id = "servposr";
        toggleServPos = 1;
    }
    else {
        toggleServ = 1;
        id = "servposl";
        toggleServPos = 0;
    }

    curState = STATES.INIT;

    execute(id);
}


function startServ()
{
    if(first_serv == 1) {
        return;
    }

    if(this.id == "servposr") {
        toggleServ = 0;
    }
    else {
        toggleServ = 1;
    }

    curState = STATES.INIT;

    execute(this.id);
}


function startRecv()
{
    showAlert("startRecv id=" + this.id);
    if(first_serv == 1) {
        return;
    }

    if(this.id == "recvposr") {
        toggleRecv = 0;
    }
    else {
        toggleRecv = 1;
    }

    curState = STATES.INIT;
    execute(this.id);
    $(this.id).removeClass('active');
}


function unbindAll()
{
    $('#rse, #b_rse, #lse, #b_lse, #lsc, #rsc, #b_lsc, #b_rsc, #cm, #b_cm').removeClass('highlightr');
    $('#rse, #b_rse, #lse, #b_lse, #lsc, #rsc, #b_lsc, #b_rsc, #cm, #b_cm').removeClass('highlight2');
    $('#rse, #b_rse, #lse, #b_lse, #lsc, #rsc, #b_lsc, #b_rsc, #cm, #b_cm').removeClass('highlight');
    $('#rse, #b_rse, #lse, #b_lse, #lsc, #rsc, #b_lsc, #b_rsc, #cm, #b_cm').unbind('click', execute);

    $('#net_r, #b_net_r, #net_l, #b_net_l').unbind('click', execute);
    $('#net_r, #b_net_r, #net_l, #b_net_l').hide();

    $('#net_l, #b_net_l, #net_r, #b_net_r').removeClass('highlight2');
    $('#net_l, #b_net_l, #net_r, #b_net_r').addClass('highlight');

    $('#out_err, #b_out_err').removeClass('highlight');
    $('#out_err, #b_out_err').unbind('click', execute);

    $('#rsc_ace, #rsc_winner, #rsc_return, #lsc_ace, #lsc_winner, #lsc_return').unbind('click', execute);
    $('#rsc_ace, #rsc_winner, #rsc_return, #lsc_ace, #lsc_winner, #lsc_return').hide();

    $('#b_rsc_ace, #b_rsc_winner, #b_rsc_return, #b_lsc_ace, #b_lsc_winner, #b_lsc_return').unbind('click', execute);
    $('#b_rsc_ace, #b_rsc_winner, #b_rsc_return, #b_lsc_ace, #b_lsc_winner, #b_lsc_return').hide();

    $('#cm, #b_cm').html('');

    first_serv = 0;
}


function showStats() {
    $('#p1_name1').html(p1.name);
    $('#p1_dbl_flt').html(p1.dbl_flts);
    $('#p1_net_err').html(p1.net_errs);
    $('#p1_aces').html(p1.aces);
    $('#p1_sec_aces').html(p1.sec_aces);
    $('#p1_serv_winners').html(p1.serv_winners);
    $('#p1_sec_serv_winners').html(p1.sec_serv_winners);

    $('#p2_name1').html(p2.name);
    $('#p2_dbl_flt').html(p2.dbl_flts);
    $('#p2_net_err').html(p2.net_errs);
    $('#p2_aces').html(p2.aces);
    $('#p2_sec_aces').html(p2.sec_aces);
    $('#p2_serv_winners').html(p2.serv_winners);
    $('#p2_sec_serv_winners').html(p2.sec_serv_winners);

}


function showScore() {
    sb.updateScore();

    $('.floaty').toggleFloaty();
    setTimeout("$('.floaty').toggleFloaty()", 2000);
}


function moveToINPLAY()
{
    //unbind
    unbindAll();

    //bind for INPLAY
    $('#rse, #b_rse, #lse, #b_lse').addClass('highlightr');
    $('#rse, #b_rse, #lse, #b_lse').bind('click', execute);
    $('#net_l, #b_net_l, #net_r, #b_net_r').bind('click', execute);
    $('#net_l, #b_net_l, #net_r, #b_net_r').show();

    $('#out_err, #b_out_err').addClass('highlight');
    $('#out_err, #b_out_err').bind('click', execute);

    $('#cm, #b_cm').html('WINNER');
    $('#cm, #b_cm').addClass('highlightr');
    $('#cm, #b_cm').bind('click', execute);
    $('#debug').html('State = ' + curState + '->INPLAY');
    $('#comment').html('Tap the highlighted areas to finish the point');
    curState = STATES.INPLAY;
}

function sendData() {
    query = "email=" + email + 
            "&desc=" + desc +
            "&name=" + p1.name + 
            "&vs=" + p2.name + 
            "&dbl_flts=" + p1.dbl_flts + 
            "&aces=" + p1.aces + 
            "&sec_aces=" + p1.sec_aces + 
            "&winners=" + p1.serv_winners + 
            "&sec_winners=" + p1.sec_serv_winners + 
            "&net_errs=" + p1.net_errs + 
            "&unf_errs=" + p1.unf_errs + 
            "&points=" + p1.points + 
            "&serves=" + p1.serves + 

            "&p1score=" + p1.score + 
            "&p2score=" + p2.score + 
            "&p1set1=" + p1.sets[0] + 
            "&p2set1=" + p2.sets[0] + 
            "&p1set2=" + p1.sets[1] + 
            "&p2set2=" + p2.sets[1] + 
            "&p1set3=" + p1.sets[2] + 
            "&p2set3=" + p2.sets[2] + 
            "&curset=" + sb.curset + 
            "&mo=" + sb.matchover;
    $.ajax({
       type: "GET",
       url: "../store",
       data: query,
       success: function(msg){
         $('#comment').html("Data Saved " + msg );
       }
     });
}

function recvData() {
    if (email == "") {
        return;
    }
    url = "../retrieve?email=" + email + "&json=1";
    $.getJSON(url,
        function(data) {
            //p2.name = data[0].p2name;
            //p1.name = data[0].p1name;
            p1.dbl_flts = data[0].dbl_flts;
            p1.net_errs = data[0].net_errs;
            p1.aces = data[0].aces;
            p1.serv_winners = data[0].winners;
            p1.sec_aces = data[0].sec_aces;
            p1.sec_serv_winners = data[0].sec_winners;
            p1.unf_errs = data[0].unf_errs;
            p1.serves = data[0].serves;
            p1.points = data[0].points;

            p1.score = data[0].p1score;
            p2.score = data[0].p2score;
            p1.sets[0] = data[0].p1set1;
            p2.sets[0] = data[0].p2set1;
            p1.sets[1] = data[0].p1set2;
            p2.sets[1] = data[0].p2set2;
            p1.sets[2] = data[0].p1set3;
            p2.sets[2] = data[0].p2set3;
            sb.curset = data[0].curset;
            p1.games = p1.sets[sb.curset];
            p2.games = p2.sets[sb.curset];
    });
}


function setup_clk() {

    $("#setup_submit").one('click', setup_submit_clk);
    showAlert("Setup Click new");
    //if there is an incomplete game, provide option to force save it
    if (match.matchover === 0) {
        $("#email").val(email);
        $("#player").val(p1.name);
        $("#opponent").val(p2.name);
        $("#setup > form > p").html("There is an incomplete match in the database. To continue with the same match, uncheck below and submit.");
        $("#setup_info > #setup_checkbox").html("<li><input type='checkbox' id='force' value=1 title='Create a new match? This will archive the current match.'></li>");
    }
}


function setup_submit_clk() {
    if( $("#force").val() == undefined ) {
        showAlert("Setup Submit force=" + $('#force').val());
        p1.name = $("#player").val();
        p2.name = $("#opponent").val();
        email = $("#email").val();
        match.matchover = 0;
        create_match();
    }
    else if( $("#force").is(':checked') == true ) {
        showAlert("Setup Submit force true=" + $('#force').val());
        //finish the current match and create a new one
        match.matchover = 1;
        update_match();
        p1.name = $("#player").val();
        p2.name = $("#opponent").val();
        email = $("#email").val();
        create_match();
    }
    else if( $("#force").is(':checked') == false ) {
        showAlert("Setup Submit force false=" + $('#force').val());
        p1.name = $("#player").val();
        p2.name = $("#opponent").val();
        email = $("#email").val();
        match.matchover = 0;
        update_match();
    }
}


//DB functions
/*
Local Database
*/



function create_match() {
    match.id = ++max_id;
    timestamp = new Date().getTime();

    reset();

    db.transaction( 
    function (tx) {
        tx.executeSql("INSERT INTO DoubleFault (id, timestamp, email, player, opponent, p1_df, p2_df, p1_neterrs, p2_neterrs, p1_aces, p2_aces, p1_aces2, p2_aces2, p1_wins, p2_wins, p1_wins2, p2_wins2, matchover) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [match.id, timestamp, email, p1.name, p2.name, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        function(tx, rs) {
            showAlert("create_match insert success id=" + match.id);
        }, 
        function(tx, err) {
            showAlert("Failed to create a new match entry id=" + match.id);
        });

        tx.executeSql("INSERT INTO Scoreboard (id, player, opponent, p1_score, p2_score, p1_set1, p2_set1, p1_set2, p2_set2, p1_set3, p2_set3) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [match.id, p1.name, p2.name, 0, 0, 0, 0, 0, 0, 0, 0],
        function(tx, rs) {
            showAlert("create_score insert success id=" + match.id);
        }, 
        function(tx, err) {
            showAlert("Failed to create a new scoreboard entry id=" + match.id);
        });
    }); 
}


function update_match() {
    timestamp = new Date().getTime();

    mo = match.matchover;
    id = match.id;
    player = p1.name;
    opponent = p2.name;
    e = email;

    db.transaction(function (tx) {
        tx.executeSql("UPDATE DoubleFault SET timestamp = ?, email = ?, player = ?, opponent = ?, p1_df = ?, p2_df = ?, p1_neterrs = ?, p2_neterrs = ?, p1_aces = ?, p2_aces = ?, p1_aces2 = ?, p2_aces2 = ?, p1_wins = ?, p2_wins = ?, p1_wins2 = ?, p2_wins2 = ?, matchover = ? WHERE id = ?", [timestamp, e, player, opponent, p1.dbl_flts, p2.dbl_flts, p1.net_errs, p2.net_errs, p1.aces, p2.aces, p1.sec_aces, p2.sec_aces, p1.serv_winners, p2.serv_winners, p1.sec_serv_winners, p2.sec_serv_winners, mo, id],
        function(tx, rs) {
            showAlert("update_match success id=" + id);
        },
        function(tx, err) {
            showAlert("update_match failed id=" + id);
        });
    }); 
}


function delete_match(id) {
    db.transaction(function (tx) {
        tx.executeSql("DELETE FROM DoubleFault WHERE id = ?", [id]);
        tx.executeSql("DELETE FROM Scoreboard WHERE id = ?", [id]);
    }); 
    return true;
}
